﻿using Duende.IdentityServer.Models;
using Duende.IdentityServer.Validation;
using Service.Auth.Api.Application.Query;
using Service.Auth.Domain.AggregatesModel;
using Service.Auth.Model.Enum;
using Service.Core.Redis.Services;
using Service.Framework.ApplicationEventBus;
using Service.Framework.Packet;

namespace Service.Auth.Api.Application.IdsValidator
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="httpContextAccessor"></param>
    /// <param name="applicationEventBus"></param>
    /// <param name="redisService"></param>
    public class BaseResourceOwnerValidator(
        IHttpContextAccessor httpContextAccessor,
        IApplicationEventBus applicationEventBus, IRedisService redisService,
        UserQueryService userQueryService, SystemQueryService systemQueryService)
    {


        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public async Task<(GrantValidationResult? result, User? user)> ValidateAsync(string userName, string client)
        {
            var user = await userQueryService.QueryUserByAccount(userName);
            if (user == null)
            {
                return (new GrantValidationResult(TokenRequestErrors.InvalidTarget, "用户不存在，请进行注册。",
                    new Dictionary<string, object>
                {
                        { "code", StatusCode.NoQueryResults }
                }), null);
            }
            var systems = await systemQueryService.QuerySystemsByIds(user.UserSystemRoles?.Select(s => s.SystemId)?.ToList() ?? new());
            if (!systems.Any(s => s.ClientId.Equals(client)))
            {
                return (new GrantValidationResult(TokenRequestErrors.InvalidTarget,
                   "登录失败，用户无此系统权限，请联系管理员。"), null);
            }

            if (user.Status.Equals(UsetStatusEnum.Stop))
            {
                return (new GrantValidationResult(TokenRequestErrors.InvalidTarget,
                   "登录失败，用户已被封禁，请联系管理员。", new Dictionary<string, object>
                 {
                        { "code", StatusCode.IllegalBussiness }
                 }), null);
            }

            return (null, user);


        }


        /// <summary>
        /// 验证用户是否被锁
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public async Task<(bool anyLock, string? msg)> VerifyAccountLock(string userName)
        {
            string lockKey = $"{nameof(User)}:LockAccountLogin:{userName}";
            var userLockValue = await redisService.Database.StringGetAsync(lockKey);
            return (userLockValue.HasValue, userLockValue);
        }

        /// <summary>
        /// 设置用户错误次数
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public async Task SetAccountErrorCount(string userName)
        {
            var accErrotCountKey = $"{nameof(User)}:AccountLoginErrorCount:{userName}";
            var accErrotCountValue = await redisService.Database.StringGetAsync(accErrotCountKey);
            var errorCount = 0;
            if (accErrotCountValue.HasValue)
                errorCount = (int)accErrotCountValue;
            errorCount += 1;
            await redisService.Database.StringSetAsync(accErrotCountKey, errorCount, TimeSpan.FromMinutes(10));
            var lockKey = $"{nameof(User)}:LockAccountLogin:{userName}";


            if (errorCount >= 10)
            {
                await redisService.Database.StringSetAsync(lockKey, $"用户账号：{userName}被锁定,请1天后再试。", TimeSpan.FromDays(1));
            }
            else if (errorCount > 5)
            {
                await redisService.Database.StringSetAsync(lockKey, $"用户账号：{userName}被锁定,请30分钟后再试。", TimeSpan.FromMinutes(30));
            }
            else if (errorCount == 5)
            {
                await redisService.Database.StringSetAsync(lockKey, $"用户账号：{userName}被锁定,请10分钟后再试。", TimeSpan.FromMinutes(10));
            }

        }
    }
}
